package com.datagateway.controller;

import com.datagateway.component.DataBackupManager;
import com.datagateway.component.DataRecoveryManager;
import com.datagateway.model.ProcessedData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据备份和恢复控制器
 * 提供数据备份和恢复的API接口
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@RestController
@RequestMapping("/api/backup")
public class DataBackupController {

    @Autowired
    private DataBackupManager dataBackupManager;

    @Autowired
    private DataRecoveryManager dataRecoveryManager;

    /**
     * 获取备份统计信息
     * 
     * @return 统计信息
     */
    @GetMapping("/statistics")
    public Map<String, Object> getBackupStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataBackupManager.BackupStatistics statistics = dataBackupManager.getStatistics();
            
            result.put("success", true);
            result.put("statistics", statistics);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取备份统计信息失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取恢复统计信息
     * 
     * @return 统计信息
     */
    @GetMapping("/recovery/statistics")
    public Map<String, Object> getRecoveryStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataRecoveryManager.RecoveryStatistics statistics = dataRecoveryManager.getStatistics();
            
            result.put("success", true);
            result.put("statistics", statistics);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取恢复统计信息失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 备份数据
     * 
     * @param request 备份请求
     * @return 备份任务ID
     */
    @PostMapping("/backup")
    public Map<String, Object> backupData(@RequestBody BackupRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 创建ProcessedData对象
            ProcessedData data = new ProcessedData();
            data.setId(request.getDataId());
            data.setSourceTopic(request.getSourceTopic());
            data.setPartition(request.getPartition());
            data.setOffset(request.getOffset());
            data.setDataSize(request.getDataSize());
            data.setTransformedData(request.getTransformedData());
            
            // 执行备份
            String taskId = dataBackupManager.backupData(data, request.getBackupType());
            
            if (taskId != null) {
                result.put("success", true);
                result.put("taskId", taskId);
                result.put("message", "数据备份任务已创建");
                result.put("timestamp", System.currentTimeMillis());
            } else {
                result.put("success", false);
                result.put("message", "数据备份任务创建失败");
                result.put("timestamp", System.currentTimeMillis());
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "数据备份失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 批量备份数据
     * 
     * @param request 批量备份请求
     * @return 备份任务ID列表
     */
    @PostMapping("/backup/batch")
    public Map<String, Object> backupDataBatch(@RequestBody BatchBackupRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ProcessedData> dataList = request.getDataList();
            List<String> taskIds = dataBackupManager.backupDataBatch(dataList, request.getBackupType());
            
            result.put("success", true);
            result.put("taskIds", taskIds);
            result.put("taskCount", taskIds.size());
            result.put("message", "批量数据备份任务已创建");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "批量数据备份失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 恢复数据
     * 
     * @param request 恢复请求
     * @return 恢复任务ID
     */
    @PostMapping("/recovery")
    public Map<String, Object> recoverData(@RequestBody RecoveryRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String taskId = dataRecoveryManager.recoverData(request.getBackupId(), request.getRecoveryType());
            
            if (taskId != null) {
                result.put("success", true);
                result.put("taskId", taskId);
                result.put("message", "数据恢复任务已创建");
                result.put("timestamp", System.currentTimeMillis());
            } else {
                result.put("success", false);
                result.put("message", "数据恢复任务创建失败");
                result.put("timestamp", System.currentTimeMillis());
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "数据恢复失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 批量恢复数据
     * 
     * @param request 批量恢复请求
     * @return 恢复任务ID列表
     */
    @PostMapping("/recovery/batch")
    public Map<String, Object> recoverDataBatch(@RequestBody BatchRecoveryRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<String> taskIds = dataRecoveryManager.recoverDataBatch(request.getBackupIds(), request.getRecoveryType());
            
            result.put("success", true);
            result.put("taskIds", taskIds);
            result.put("taskCount", taskIds.size());
            result.put("message", "批量数据恢复任务已创建");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "批量数据恢复失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 自动恢复数据
     * 
     * @param dataId 数据ID
     * @return 恢复的数据
     */
    @PostMapping("/recovery/auto/{dataId}")
    public Map<String, Object> autoRecoverData(@PathVariable String dataId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ProcessedData recoveredData = dataRecoveryManager.autoRecoverData(dataId);
            
            if (recoveredData != null) {
                result.put("success", true);
                result.put("dataId", dataId);
                result.put("recoveredData", recoveredData);
                result.put("message", "自动数据恢复成功");
                result.put("timestamp", System.currentTimeMillis());
            } else {
                result.put("success", false);
                result.put("message", "自动数据恢复失败，未找到备份或恢复失败");
                result.put("timestamp", System.currentTimeMillis());
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "自动数据恢复失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取备份任务状态
     * 
     * @param taskId 任务ID
     * @return 备份任务状态
     */
    @GetMapping("/task/{taskId}")
    public Map<String, Object> getBackupTaskStatus(@PathVariable String taskId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataBackupManager.BackupTask task = dataBackupManager.getBackupTaskStatus(taskId);
            
            if (task != null) {
                result.put("success", true);
                result.put("task", task);
                result.put("timestamp", System.currentTimeMillis());
            } else {
                result.put("success", false);
                result.put("message", "备份任务不存在");
                result.put("timestamp", System.currentTimeMillis());
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取备份任务状态失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取恢复任务状态
     * 
     * @param taskId 任务ID
     * @return 恢复任务状态
     */
    @GetMapping("/recovery/task/{taskId}")
    public Map<String, Object> getRecoveryTaskStatus(@PathVariable String taskId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataRecoveryManager.RecoveryTask task = dataRecoveryManager.getRecoveryTaskStatus(taskId);
            
            if (task != null) {
                result.put("success", true);
                result.put("task", task);
                result.put("timestamp", System.currentTimeMillis());
            } else {
                result.put("success", false);
                result.put("message", "恢复任务不存在");
                result.put("timestamp", System.currentTimeMillis());
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取恢复任务状态失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取所有备份任务状态
     * 
     * @return 备份任务状态列表
     */
    @GetMapping("/tasks")
    public Map<String, Object> getAllBackupTaskStatus() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<DataBackupManager.BackupTask> tasks = dataBackupManager.getAllBackupTaskStatus();
            
            result.put("success", true);
            result.put("tasks", tasks);
            result.put("taskCount", tasks.size());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取备份任务状态失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取所有恢复任务状态
     * 
     * @return 恢复任务状态列表
     */
    @GetMapping("/recovery/tasks")
    public Map<String, Object> getAllRecoveryTaskStatus() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<DataRecoveryManager.RecoveryTask> tasks = dataRecoveryManager.getAllRecoveryTaskStatus();
            
            result.put("success", true);
            result.put("tasks", tasks);
            result.put("taskCount", tasks.size());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取恢复任务状态失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 删除备份
     * 
     * @param backupId 备份ID
     * @return 操作结果
     */
    @DeleteMapping("/delete/{backupId}")
    public Map<String, Object> deleteBackup(@PathVariable String backupId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean deleted = dataBackupManager.deleteBackup(backupId);
            
            if (deleted) {
                result.put("success", true);
                result.put("backupId", backupId);
                result.put("message", "备份删除成功");
                result.put("timestamp", System.currentTimeMillis());
            } else {
                result.put("success", false);
                result.put("message", "备份删除失败，备份不存在");
                result.put("timestamp", System.currentTimeMillis());
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "删除备份失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 清理过期备份
     * 
     * @return 操作结果
     */
    @PostMapping("/cleanup")
    public Map<String, Object> cleanupExpiredBackups() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            dataBackupManager.cleanupExpiredBackups();
            
            result.put("success", true);
            result.put("message", "过期备份清理完成");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "清理过期备份失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 设置备份配置
     * 
     * @param request 配置请求
     * @return 操作结果
     */
    @PostMapping("/config")
    public Map<String, Object> setBackupConfig(@RequestBody BackupConfigRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            dataBackupManager.setBackupConfig(
                request.isEnabled(),
                request.getRetentionDays(),
                request.getMaxConcurrent(),
                request.isCompression(),
                request.getFormat()
            );
            
            result.put("success", true);
            result.put("enabled", request.isEnabled());
            result.put("retentionDays", request.getRetentionDays());
            result.put("maxConcurrent", request.getMaxConcurrent());
            result.put("compression", request.isCompression());
            result.put("format", request.getFormat());
            result.put("message", "备份配置已更新");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置备份配置失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 设置恢复配置
     * 
     * @param request 配置请求
     * @return 操作结果
     */
    @PostMapping("/recovery/config")
    public Map<String, Object> setRecoveryConfig(@RequestBody RecoveryConfigRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            dataRecoveryManager.setRecoveryConfig(
                request.isEnabled(),
                request.getMaxConcurrent(),
                request.getTimeoutMinutes(),
                request.isAutoRecovery()
            );
            
            result.put("success", true);
            result.put("enabled", request.isEnabled());
            result.put("maxConcurrent", request.getMaxConcurrent());
            result.put("timeoutMinutes", request.getTimeoutMinutes());
            result.put("autoRecovery", request.isAutoRecovery());
            result.put("message", "恢复配置已更新");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置恢复配置失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 备份请求类
     */
    public static class BackupRequest {
        private String dataId;
        private String sourceTopic;
        private int partition;
        private long offset;
        private long dataSize;
        private java.util.Map<String, Object> transformedData;
        private DataBackupManager.BackupType backupType;

        // Getter和Setter方法
        public String getDataId() { return dataId; }
        public void setDataId(String dataId) { this.dataId = dataId; }
        
        public String getSourceTopic() { return sourceTopic; }
        public void setSourceTopic(String sourceTopic) { this.sourceTopic = sourceTopic; }
        
        public int getPartition() { return partition; }
        public void setPartition(int partition) { this.partition = partition; }
        
        public long getOffset() { return offset; }
        public void setOffset(long offset) { this.offset = offset; }
        
        public long getDataSize() { return dataSize; }
        public void setDataSize(long dataSize) { this.dataSize = dataSize; }
        
        public java.util.Map<String, Object> getTransformedData() { return transformedData; }
        public void setTransformedData(java.util.Map<String, Object> transformedData) { this.transformedData = transformedData; }
        
        public DataBackupManager.BackupType getBackupType() { return backupType; }
        public void setBackupType(DataBackupManager.BackupType backupType) { this.backupType = backupType; }
    }

    /**
     * 批量备份请求类
     */
    public static class BatchBackupRequest {
        private java.util.List<ProcessedData> dataList;
        private DataBackupManager.BackupType backupType;

        // Getter和Setter方法
        public java.util.List<ProcessedData> getDataList() { return dataList; }
        public void setDataList(java.util.List<ProcessedData> dataList) { this.dataList = dataList; }
        
        public DataBackupManager.BackupType getBackupType() { return backupType; }
        public void setBackupType(DataBackupManager.BackupType backupType) { this.backupType = backupType; }
    }

    /**
     * 恢复请求类
     */
    public static class RecoveryRequest {
        private String backupId;
        private DataRecoveryManager.RecoveryType recoveryType;

        // Getter和Setter方法
        public String getBackupId() { return backupId; }
        public void setBackupId(String backupId) { this.backupId = backupId; }
        
        public DataRecoveryManager.RecoveryType getRecoveryType() { return recoveryType; }
        public void setRecoveryType(DataRecoveryManager.RecoveryType recoveryType) { this.recoveryType = recoveryType; }
    }

    /**
     * 批量恢复请求类
     */
    public static class BatchRecoveryRequest {
        private java.util.List<String> backupIds;
        private DataRecoveryManager.RecoveryType recoveryType;

        // Getter和Setter方法
        public java.util.List<String> getBackupIds() { return backupIds; }
        public void setBackupIds(java.util.List<String> backupIds) { this.backupIds = backupIds; }
        
        public DataRecoveryManager.RecoveryType getRecoveryType() { return recoveryType; }
        public void setRecoveryType(DataRecoveryManager.RecoveryType recoveryType) { this.recoveryType = recoveryType; }
    }

    /**
     * 备份配置请求类
     */
    public static class BackupConfigRequest {
        private boolean enabled = true;
        private int retentionDays = 30;
        private int maxConcurrent = 3;
        private boolean compression = true;
        private String format = "json";

        // Getter和Setter方法
        public boolean isEnabled() { return enabled; }
        public void setEnabled(boolean enabled) { this.enabled = enabled; }
        
        public int getRetentionDays() { return retentionDays; }
        public void setRetentionDays(int retentionDays) { this.retentionDays = retentionDays; }
        
        public int getMaxConcurrent() { return maxConcurrent; }
        public void setMaxConcurrent(int maxConcurrent) { this.maxConcurrent = maxConcurrent; }
        
        public boolean isCompression() { return compression; }
        public void setCompression(boolean compression) { this.compression = compression; }
        
        public String getFormat() { return format; }
        public void setFormat(String format) { this.format = format; }
    }

    /**
     * 恢复配置请求类
     */
    public static class RecoveryConfigRequest {
        private boolean enabled = true;
        private int maxConcurrent = 2;
        private long timeoutMinutes = 30;
        private boolean autoRecovery = false;

        // Getter和Setter方法
        public boolean isEnabled() { return enabled; }
        public void setEnabled(boolean enabled) { this.enabled = enabled; }
        
        public int getMaxConcurrent() { return maxConcurrent; }
        public void setMaxConcurrent(int maxConcurrent) { this.maxConcurrent = maxConcurrent; }
        
        public long getTimeoutMinutes() { return timeoutMinutes; }
        public void setTimeoutMinutes(long timeoutMinutes) { this.timeoutMinutes = timeoutMinutes; }
        
        public boolean isAutoRecovery() { return autoRecovery; }
        public void setAutoRecovery(boolean autoRecovery) { this.autoRecovery = autoRecovery; }
    }
}
